package com.example.recyclerviewlearn;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.Arrays;
import java.util.concurrent.RejectedExecutionException;

import androidx.annotation.Px;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class myLinearLayoutManager extends RecyclerView.LayoutManager {
    private static final String TAG = "myLinearLayoutManager";

    private Context mContext;

    int totalHeight = 0;

    //保存所有的Item的上下左右的偏移量信息
    private SparseArray<Rect> allItemFrames = new SparseArray<>();

    //记录Item是否出现过屏幕且还没有回收。true表示出现过屏幕上，并且还没被回收
    private SparseBooleanArray hasAttachedItems = new SparseBooleanArray();

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        //在布局之前，将所有的子View先Detach掉，放入到Scrap缓存中
        detachAndScrapAttachedViews(recycler);

        // 定义竖直方向的偏移量
        int offsetY = 0;

        totalHeight = 0;

        for (int i = 0; i < getItemCount(); i++) {
            View view = recycler.getViewForPosition(i);
            addView(view);
            measureChildWithMargins(view, 0, 0);

            // 获取宽高尺寸
            int width = getDecoratedMeasuredWidth(view);

            int height = getDecoratedMeasuredHeight(view);

            totalHeight += height;
            Rect frame = allItemFrames.get(i);
            if (frame == null) {
                frame = new Rect();
            }
            frame.set(0, offsetY, width, offsetY + height);
            // 将当前的Item的Rect边界数据保存
            allItemFrames.put(i, frame);
            // 由于已经调用了detachAndScrapAttachedViews，因此需要将当前的Item设置为未出现过
            hasAttachedItems.put(i, false);

//            // 将view进行布局
//            layoutDecorated(view, 0, offsetY, width, offsetY + height);

            // 将垂直方向增大height
            offsetY += height;

            totalHeight += height;
        }
        //如果所有子View的高度和没有填满RecyclerView的高度，
        // 则将高度设置为RecyclerView的高度
        totalHeight = Math.max(totalHeight, getVerticalSpace());
        recycleAndFillItems(recycler, state);
    }

    /**
     * 回收不需要的item，并且将需要显示的item从缓存中取出
     */
    private void recycleAndFillItems(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (state.isPreLayout()) {
            return;
        }

        // 当前需要显示的区域
        Rect displayFrame = new Rect(0, verticalScrollOffset, getHorizontalSpace(),
                verticalScrollOffset + getVerticalSpace());

        /**
         * 将划出屏幕的items回收到Recycle缓存中
         */
        Rect childFrame = new Rect();
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            childFrame.left = getDecoratedLeft(child);
            childFrame.right = getDecoratedRight(child);
            childFrame.top = getDecoratedTop(child);
            childFrame.bottom = getDecoratedBottom(child);

            // 两个区域没有相交，那么就回收该item
            if (!Rect.intersects(displayFrame, childFrame)) {
                removeAndRecycleView(child, recycler);
            }
        }

        //重新显示需要出现在屏幕的子View
        for (int i = 0; i < getItemCount(); i++) {

            if (Rect.intersects(displayFrame, allItemFrames.get(i))) {

                View scrap = recycler.getViewForPosition(i);
                measureChildWithMargins(scrap, 0, 0);
                addView(scrap);

                Rect frame = allItemFrames.get(i);

                // 将这个item布局出来
                layoutDecorated(scrap, frame.left,
                        frame.top - verticalScrollOffset,
                        frame.right, frame.bottom - verticalScrollOffset);
            }
        }
    }

    private int getHorizontalSpace() {
        return getWidth() - getPaddingLeft() - getPaddingRight();
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(
                RecyclerView.LayoutParams.WRAP_CONTENT,
                RecyclerView.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public boolean canScrollVertically() {
        return true;
    }

    int verticalScrollOffset = 0;

    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {

        //先detach掉所有的子View
        detachAndScrapAttachedViews(recycler);

        Log.i(TAG, "scrollVerticallyBy: dy" + dy + "totalHeight" + totalHeight);
        //实际要滑动的距离
        int travel = dy;

        //如果滑动到最顶部
        if (verticalScrollOffset + dy < 0) {
            travel = -verticalScrollOffset;
        } else if (verticalScrollOffset + dy > totalHeight - getVerticalSpace()) {
            // 当滑动到最底部的时候没办法继续滑动，只滑动一定的距离
            Log.i(TAG, "scrollVerticallyBy: dy biger");
            travel = totalHeight - getVerticalSpace() - verticalScrollOffset;
            Log.i(TAG, "scrollVerticallyBy: travel" + travel);
        }

        //将竖直方向的偏移量+travel
        verticalScrollOffset += travel;

        offsetChildrenVertical(-travel);
        recycleAndFillItems(recycler, state);

        Log.d("--->", " childView count:" + getChildCount());
        return travel;
    }
    //用于获取RecyclerView在垂直方向上的可用空间
    private int getVerticalSpace() {
        return getHeight() - getPaddingBottom() - getPaddingTop();
    }
}
